<script setup>
import { ref, computed, watch } from 'vue';

// 公式分组定义
const formulaGroups = [
  { id: 'logical', name: '逻辑函数' },
  { id: 'math', name: '数学函数' },
  { id: 'text', name: '文本函数' },
  { id: 'date', name: '日期函数' },
  { id: 'array', name: '数组公式' }
];

// 所有公式定义（基于JS内置函数扩展）
const allFormulas = [
  // 逻辑函数
  {
    id: 'if',
    group: 'logical',
    name: 'IF',
    expression: 'IF(条件, 结果为真时的值, 结果为假时的值)',
    description: '根据条件判断返回不同结果。如果条件为真，返回第二个参数；如果条件为假，返回第三个参数。',
    notes: '条件通常是比较表达式，如A>B或A=B',
    params: [
      { key: 'condition', label: '条件', type: 'text', value: '', placeholder: '例如: 5>3 或 A==B' },
      { key: 'valueIfTrue', label: '真值', value: '', placeholder: '条件为真时返回的值' },
      { key: 'valueIfFalse', label: '假值', value: '', placeholder: '条件为假时返回的值' }
    ],
    variableParams: false, // 不支持动态参数
    calculate: (params) => {
      try {
        // 简化的表达式评估
        const condition = new Function('return ' + params.condition)();
        return condition ? params.valueIfTrue : params.valueIfFalse;
      } catch (e) {
        throw new Error('条件表达式无效，请使用简单比较如 "5>3" 或 "A==B"');
      }
    }
  },
  {
    id: 'and',
    group: 'logical',
    name: 'AND',
    expression: 'AND(条件1, 条件2, ...)',
    description: '判断所有条件是否都为真。只有当所有条件都为真时，返回TRUE；否则返回FALSE。',
    params: [
      { key: 'cond1', label: '条件1', type: 'text', value: '', placeholder: '例如: 5>3' },
      { key: 'cond2', label: '条件2', type: 'text', value: '', placeholder: '例如: 10<20' }
    ],
    variableParams: true, // 支持动态参数
    paramTemplate: { key: 'cond', label: '条件', type: 'text', value: '', placeholder: '例如: 5>3' },
    calculate: (params) => {
      try {
        const cond1 = new Function('return ' + params.cond1)();
        const cond2 = new Function('return ' + params.cond2)();
        return cond1 && cond2 ? 'TRUE' : 'FALSE';
      } catch (e) {
        throw new Error('条件表达式无效');
      }
    }
  },
  {
    id: 'or',
    group: 'logical',
    name: 'OR',
    expression: 'OR(条件1, 条件2, ...)',
    description: '判断是否至少有一个条件为真。只要有一个条件为真，返回TRUE；否则返回FALSE。',
    params: [
      { key: 'cond1', label: '条件1', type: 'text', value: '', placeholder: '例如: 5>3' },
      { key: 'cond2', label: '条件2', type: 'text', value: '', placeholder: '例如: 10<20' }
    ],
    variableParams: true, // 不支持动态参数
    paramTemplate: { key: 'cond', label: '条件', type: 'text', value: '', placeholder: '例如: 5>3' },
    calculate: (params) => {
      try {
        const cond1 = new Function('return ' + params.cond1)();
        const cond2 = new Function('return ' + params.cond2)();
        return cond1 || cond2 ? 'TRUE' : 'FALSE';
      } catch (e) {
        throw new Error('条件表达式无效');
      }
    }
  },
  {
    id: 'not',
    group: 'logical',
    name: 'NOT',
    expression: 'NOT(条件)',
    description: '对条件的结果取反。如果条件为真，返回FALSE；如果条件为假，返回TRUE。',
    params: [
      { key: 'condition', label: '条件', type: 'text', value: '', placeholder: '例如: 5>3' }
    ],
    variableParams: false, // 不支持动态参数
    calculate: (params) => {
      try {
        const condition = new Function('return ' + params.condition)();
        return !condition ? 'TRUE' : 'FALSE';
      } catch (e) {
        throw new Error('条件表达式无效');
      }
    }
  },

  // 数学函数 (基于JS Math对象)
  {
    id: 'abs',
    group: 'math',
    name: 'ABS',
    expression: 'ABS(数值)',
    description: '返回一个数的绝对值。',
    params: [
      { key: 'number', label: '数值', type: 'number', value: null, placeholder: '输入任意数值' }
    ],
    variableParams: false, // 不支持动态参数
    calculate: (params) => {
      const num = Number(params.number);
      if (isNaN(num)) throw new Error('请输入有效的数值');
      return Math.abs(num);
    }
  },
  {
    id: 'acos',
    group: 'math',
    name: 'ACOS',
    expression: 'ACOS(数值)',
    description: '返回一个数的反余弦值（弧度）。参数必须在 -1 到 1 之间。',
    notes: '返回值为弧度，范围在 0 到 π 之间',
    params: [
      { key: 'number', label: '数值', type: 'number', value: null, placeholder: '输入-1到1之间的数值' }
    ],
    variableParams: false, // 不支持动态参数
    calculate: (params) => {
      const num = Number(params.number);
      if (isNaN(num) || num < -1 || num > 1) throw new Error('数值必须在-1到1之间');
      return Math.acos(num);
    }
  },
  {
    id: 'asin',
    group: 'math',
    name: 'ASIN',
    expression: 'ASIN(数值)',
    description: '返回一个数的反正弦值（弧度）。参数必须在 -1 到 1 之间。',
    notes: '返回值为弧度，范围在 -π/2 到 π/2 之间',
    params: [
      { key: 'number', label: '数值', type: 'number', value: null, placeholder: '输入-1到1之间的数值' }
    ],
    variableParams: false, // 不支持动态参数
    calculate: (params) => {
      const num = Number(params.number);
      if (isNaN(num) || num < -1 || num > 1) throw new Error('数值必须在-1到1之间');
      return Math.asin(num);
    }
  },
  {
    id: 'atan',
    group: 'math',
    name: 'ATAN',
    expression: 'ATAN(数值)',
    description: '返回一个数的反正切值（弧度）。',
    notes: '返回值为弧度，范围在 -π/2 到 π/2 之间',
    params: [
      { key: 'number', label: '数值', type: 'number', value: null, placeholder: '输入任意数值' }
    ],
    variableParams: false, // 不支持动态参数
    calculate: (params) => {
      const num = Number(params.number);
      if (isNaN(num)) throw new Error('请输入有效的数值');
      return Math.atan(num);
    }
  },
  {
    id: 'atan2',
    group: 'math',
    name: 'ATAN2',
    expression: 'ATAN2(y坐标, x坐标)',
    description: '返回从x轴到点(x, y)的角度（弧度）。',
    notes: '返回值为弧度，范围在 -π 到 π 之间',
    params: [
      { key: 'y', label: 'y坐标', type: 'number', value: null, placeholder: '输入y坐标' },
      { key: 'x', label: 'x坐标', type: 'number', value: null, placeholder: '输入x坐标' }
    ],
    variableParams: false, // 不支持动态参数
    calculate: (params) => {
      const y = Number(params.y);
      const x = Number(params.x);
      if (isNaN(y) || isNaN(x)) throw new Error('请输入有效的数值');
      return Math.atan2(y, x);
    }
  },
  {
    id: 'ceil',
    group: 'math',
    name: 'CEIL',
    expression: 'CEIL(数值)',
    description: '返回大于或等于给定数的最小整数（向上取整）。',
    params: [
      { key: 'number', label: '数值', type: 'number', value: null, placeholder: '输入任意数值' }
    ],
    variableParams: false, // 不支持动态参数
    calculate: (params) => {
      const num = Number(params.number);
      if (isNaN(num)) throw new Error('请输入有效的数值');
      return Math.ceil(num);
    }
  },
  {
    id: 'cos',
    group: 'math',
    name: 'COS',
    expression: 'COS(弧度)',
    description: '返回一个角的余弦值。参数为弧度。',
    params: [
      { key: 'radians', label: '弧度', type: 'number', value: null, placeholder: '输入角度（弧度）' }
    ],
    variableParams: false, // 不支持动态参数
    calculate: (params) => {
      const radians = Number(params.radians);
      if (isNaN(radians)) throw new Error('请输入有效的数值');
      return Math.cos(radians);
    }
  },
  {
    id: 'exp',
    group: 'math',
    name: 'EXP',
    expression: 'EXP(数值)',
    description: '返回自然常数e的指定次幂，即e^x。',
    params: [
      { key: 'number', label: '数值', type: 'number', value: null, placeholder: '输入指数' }
    ],
    variableParams: false, // 不支持动态参数
    calculate: (params) => {
      const num = Number(params.number);
      if (isNaN(num)) throw new Error('请输入有效的数值');
      return Math.exp(num);
    }
  },
  {
    id: 'floor',
    group: 'math',
    name: 'FLOOR',
    expression: 'FLOOR(数值)',
    description: '返回小于或等于给定数的最大整数（向下取整）。',
    params: [
      { key: 'number', label: '数值', type: 'number', value: null, placeholder: '输入任意数值' }
    ],
    variableParams: false, // 不支持动态参数
    calculate: (params) => {
      const num = Number(params.number);
      if (isNaN(num)) throw new Error('请输入有效的数值');
      return Math.floor(num);
    }
  },
  {
    id: 'log',
    group: 'math',
    name: 'LOG',
    expression: 'LOG(数值, 底数)',
    description: '返回一个数以指定底数的对数。如果省略底数，则默认为自然对数。',
    params: [
      { key: 'number', label: '数值', type: 'number', value: null, placeholder: '输入正数' },
      { key: 'base', label: '底数', type: 'number', value: null, placeholder: '输入底数（可选）' }
    ],
    variableParams: false, // 不支持动态参数
    calculate: (params) => {
      const num = Number(params.number);
      if (isNaN(num) || num <= 0) throw new Error('数值必须是正数');

      const base = params.base ? Number(params.base) : null;
      if (base !== null && (isNaN(base) || base <= 0 || base === 1)) {
        throw new Error('底数必须是正数且不等于1');
      }

      return base ? Math.log(num) / Math.log(base) : Math.log(num);
    }
  },
  {
    id: 'log10',
    group: 'math',
    name: 'LOG10',
    expression: 'LOG10(数值)',
    description: '返回一个数的以10为底的对数。',
    params: [
      { key: 'number', label: '数值', type: 'number', value: null, placeholder: '输入正数' }
    ],
    variableParams: false, // 不支持动态参数
    calculate: (params) => {
      const num = Number(params.number);
      if (isNaN(num) || num <= 0) throw new Error('数值必须是正数');
      return Math.log10(num);
    }
  },
  {
    id: 'max',
    group: 'math',
    name: 'MAX',
    expression: 'MAX(数值1, 数值2, ...)',
    description: '返回一组数中的最大值。',
    params: [
      { key: 'num1', label: '数值1', type: 'number', value: null, placeholder: '输入第一个数值' },
      { key: 'num2', label: '数值2', type: 'number', value: null, placeholder: '输入第二个数值' },
      { key: 'num3', label: '数值3', type: 'number', value: null, placeholder: '输入第三个数值（可选）' }
    ],
    variableParams: true, // 支持动态参数
    paramTemplate: {key: 'num', label: '数值', type: 'number', value: null, placeholder: '输入数值'},
    calculate: (params) => {
      const values = Object.values(params).filter(v => v !== null && !isNaN(v)).map(Number);
      if (values.length === 0) throw new Error('至少需要一个有效数值');
      return Math.max(...values);
    }
  },
  {
    id: 'min',
    group: 'math',
    name: 'MIN',
    expression: 'MIN(数值1, 数值2, ...)',
    description: '返回一组数中的最小值。',
    params: [
      { key: 'num1', label: '数值1', type: 'number', value: null, placeholder: '输入第一个数值' },
      { key: 'num2', label: '数值2', type: 'number', value: null, placeholder: '输入第二个数值' },
      { key: 'num3', label: '数值3', type: 'number', value: null, placeholder: '输入第三个数值（可选）' }
    ],
    variableParams: true, // 支持动态参数
    paramTemplate: {key: 'num', label: '数值', type: 'number', value: null, placeholder: '输入数值'},
    calculate: (params) => {
      const values = Object.values(params).filter(v => v !== null && !isNaN(v)).map(Number);
      if (values.length === 0) throw new Error('至少需要一个有效数值');
      return Math.min(...values);
    }
  },
  {
    id: 'pow',
    group: 'math',
    name: 'POW',
    expression: 'POW(底数, 指数)',
    description: '返回底数的指数次方。',
    params: [
      { key: 'base', label: '底数', type: 'number', value: null, placeholder: '输入底数' },
      { key: 'exponent', label: '指数', type: 'number', value: null, placeholder: '输入指数' }
    ],
    variableParams: false, // 不支持动态参数
    calculate: (params) => {
      const base = Number(params.base);
      const exponent = Number(params.exponent);
      if (isNaN(base) || isNaN(exponent)) throw new Error('请输入有效的数值');
      return Math.pow(base, exponent);
    }
  },
  {
    id: 'random',
    group: 'math',
    name: 'RANDOM',
    expression: 'RANDOM()',
    description: '返回一个0（包含）到1（不包含）之间的随机数。',
    params: [],
    variableParams: false, // 不支持动态参数
    calculate: () => {
      return Math.random();
    }
  },
  {
    id: 'round',
    group: 'math',
    name: 'ROUND',
    expression: 'ROUND(数值, 小数位数)',
    description: '将数值四舍五入到指定的小数位数。',
    params: [
      { key: 'number', label: '数值', type: 'number', value: null, placeholder: '输入要舍入的数值' },
      { key: 'digits', label: '小数位数', type: 'number', value: 0, placeholder: '输入小数位数' }
    ],
    variableParams: false, // 不支持动态参数
    calculate: (params) => {
      const num = Number(params.number);
      const digits = Number(params.digits) || 0;
      if (isNaN(num) || isNaN(digits)) throw new Error('请输入有效的数值');

      // 处理四舍五入
      const factor = Math.pow(10, digits);
      return Math.round(num * factor) / factor;
    }
  },
  {
    id: 'sin',
    group: 'math',
    name: 'SIN',
    expression: 'SIN(弧度)',
    description: '返回一个角的正弦值。参数为弧度。',
    params: [
      { key: 'radians', label: '弧度', type: 'number', value: null, placeholder: '输入角度（弧度）' }
    ],
    variableParams: false, // 不支持动态参数
    calculate: (params) => {
      const radians = Number(params.radians);
      if (isNaN(radians)) throw new Error('请输入有效的数值');
      return Math.sin(radians);
    }
  },
  {
    id: 'sqrt',
    group: 'math',
    name: 'SQRT',
    expression: 'SQRT(数值)',
    description: '计算一个数的平方根。只接受非负数值作为参数。',
    notes: '如果输入负数，将返回错误',
    params: [
      { key: 'number', label: '数值', type: 'number', value: null, placeholder: '输入非负数值' }
    ],
    variableParams: false, // 不支持动态参数
    calculate: (params) => {
      const num = Number(params.number);
      if (isNaN(num) || num < 0) throw new Error('数值必须为非负数');
      return Math.sqrt(num);
    }
  },
  {
    id: 'sum',
    group: 'math',
    name: 'SUM',
    expression: 'SUM(数值1, 数值2, ...)',
    description: '计算所有参数的总和。可以接受多个数值参数，并返回它们的总和。',
    params: [
      { key: 'num1', label: '数值1', type: 'number', value: null, placeholder: '输入第一个数值' },
      { key: 'num2', label: '数值2', type: 'number', value: null, placeholder: '输入第二个数值' },
      { key: 'num3', label: '数值3', type: 'number', value: null, placeholder: '输入第三个数值（可选）' }
    ],
    variableParams: true, // 支持动态参数
    paramTemplate: {key: 'num', label: '数值', type: 'number', value: null, placeholder: '输入数值'},
    calculate: (params) => {
      let sum = 0;
      Object.values(params).forEach(value => {
        if (value !== null && !isNaN(value)) {
          sum += Number(value);
        }
      });
      return sum;
    }
  },
  {
    id: 'tan',
    group: 'math',
    name: 'TAN',
    expression: 'TAN(弧度)',
    description: '返回一个角的正切值。参数为弧度。',
    params: [
      { key: 'radians', label: '弧度', type: 'number', value: null, placeholder: '输入角度（弧度）' }
    ],
    variableParams: false, // 不支持动态参数
    calculate: (params) => {
      const radians = Number(params.radians);
      if (isNaN(radians)) throw new Error('请输入有效的数值');
      return Math.tan(radians);
    }
  },

  // 文本函数 (基于JS字符串方法)
  {
    id: 'char',
    group: 'text',
    name: 'CHAR',
    expression: 'CHAR(Unicode编码)',
    description: '返回指定Unicode编码对应的字符。',
    params: [
      { key: 'code', label: 'Unicode编码', type: 'number', value: null, placeholder: '输入0-65535之间的编码' }
    ],
    variableParams: false, // 不支持动态参数
    calculate: (params) => {
      const code = Number(params.code);
      if (isNaN(code) || code < 0 || code > 65535) throw new Error('编码必须在0-65535之间');
      return String.fromCharCode(code);
    }
  },
  {
    id: 'concat',
    group: 'text',
    name: 'CONCAT',
    expression: 'CONCAT(文本1, 文本2, ...)',
    description: '将多个文本字符串合并为一个文本字符串。',
    params: [
      { key: 'text1', label: '文本1', value: '', placeholder: '输入第一个文本' },
      { key: 'text2', label: '文本2', value: '', placeholder: '输入第二个文本' }
    ],
    variableParams: true, // 不支持动态参数
    paramTemplate: {key: 'text', label: '文本', value: '', placeholder: '输入文本'},
    calculate: (params) => {
      let resStr = "";
      for(let k in params) {
        resStr += params[k];
      }
      return resStr;
      // return `${params.text1 || ''}${params.text2 || ''}`;
    }
  },
  {
    id: 'includes',
    group: 'text',
    name: 'INCLUDES',
    expression: 'INCLUDES(文本, 子串)',
    description: '判断文本中是否包含指定的子串，返回TRUE或FALSE。',
    params: [
      { key: 'text', label: '文本', value: '', placeholder: '输入原始文本' },
      { key: 'substr', label: '子串', value: '', placeholder: '输入要查找的子串' }
    ],
    variableParams: false, // 不支持动态参数
    calculate: (params) => {
      return params.text.includes(params.substr) ? 'TRUE' : 'FALSE';
    }
  },
  {
    id: 'indexOf',
    group: 'text',
    name: 'INDEXOF',
    expression: 'INDEXOF(文本, 子串)',
    description: '返回子串在文本中首次出现的位置索引（从0开始），如果未找到则返回-1。',
    params: [
      { key: 'text', label: '文本', value: '', placeholder: '输入原始文本' },
      { key: 'substr', label: '子串', value: '', placeholder: '输入要查找的子串' }
    ],
    variableParams: false, // 不支持动态参数
    calculate: (params) => {
      return params.text.indexOf(params.substr);
    }
  },
  {
    id: 'lastIndexOf',
    group: 'text',
    name: 'LASTINDEXOF',
    expression: 'LASTINDEXOF(文本, 子串)',
    description: '返回子串在文本中最后出现的位置索引（从0开始），如果未找到则返回-1。',
    params: [
      { key: 'text', label: '文本', value: '', placeholder: '输入原始文本' },
      { key: 'substr', label: '子串', value: '', placeholder: '输入要查找的子串' }
    ],
    variableParams: false, // 不支持动态参数
    calculate: (params) => {
      return params.text.lastIndexOf(params.substr);
    }
  },
  {
    id: 'len',
    group: 'text',
    name: 'LEN',
    expression: 'LEN(文本)',
    description: '返回文本字符串中的字符数，包括空格。',
    params: [
      { key: 'text', label: '文本', value: '', placeholder: '输入文本' }
    ],
    variableParams: false, // 不支持动态参数
    calculate: (params) => {
      return params.text.length;
    }
  },
  {
    id: 'lower',
    group: 'text',
    name: 'LOWER',
    expression: 'LOWER(文本)',
    description: '将文本字符串转换为全小写字母。',
    params: [
      { key: 'text', label: '文本', value: '', placeholder: '输入文本' }
    ],
    variableParams: false, // 不支持动态参数
    calculate: (params) => {
      return params.text.toLowerCase();
    }
  },
  {
    id: 'replace',
    group: 'text',
    name: 'REPLACE',
    expression: 'REPLACE(文本, 搜索值, 替换值)',
    description: '将文本中所有的搜索值替换为替换值。',
    params: [
      { key: 'text', label: '文本', value: '', placeholder: '输入原始文本' },
      { key: 'search', label: '搜索值', value: '', placeholder: '输入要替换的内容' },
      { key: 'replace', label: '替换值', value: '', placeholder: '输入替换后的内容' }
    ],
    variableParams: false, // 不支持动态参数
    calculate: (params) => {
      return params.text.replace(new RegExp(params.search, 'g'), params.replace);
    }
  },
  {
    id: 'slice',
    group: 'text',
    name: 'SLICE',
    expression: 'SLICE(文本, 开始索引, 结束索引)',
    description: '从文本中提取从开始索引到结束索引（不包含）的子串。',
    params: [
      { key: 'text', label: '文本', value: '', placeholder: '输入原始文本' },
      { key: 'start', label: '开始索引', type: 'number', value: 0, placeholder: '输入开始索引' },
      { key: 'end', label: '结束索引', type: 'number', value: null, placeholder: '输入结束索引（可选）' }
    ],
    variableParams: false, // 不支持动态参数
    calculate: (params) => {
      const start = Number(params.start);
      const end = params.end !== null ? Number(params.end) : undefined;

      if (isNaN(start) || (end !== undefined && isNaN(end))) {
        throw new Error('索引必须是有效的数字');
      }

      return params.text.slice(start, end);
    }
  },
  {
    id: 'split',
    group: 'text',
    name: 'SPLIT',
    expression: 'SPLIT(文本, 分隔符)',
    description: '使用指定的分隔符将文本分割为子串数组。',
    params: [
      { key: 'text', label: '文本', value: '', placeholder: '输入原始文本' },
      { key: 'separator', label: '分隔符', value: ',', placeholder: '输入分隔符' }
    ],
    variableParams: false, // 不支持动态参数
    calculate: (params) => {
      return params.text.split(params.separator).join('; ');
    }
  },
  {
    id: 'substring',
    group: 'text',
    name: 'SUBSTRING',
    expression: 'SUBSTRING(文本, 开始索引, 长度)',
    description: '从文本中提取从开始索引开始，指定长度的子串。',
    params: [
      { key: 'text', label: '文本', value: '', placeholder: '输入原始文本' },
      { key: 'start', label: '开始索引', type: 'number', value: 0, placeholder: '输入开始索引' },
      { key: 'length', label: '长度', type: 'number', value: null, placeholder: '输入提取长度（可选）' }
    ],
    variableParams: false, // 不支持动态参数
    calculate: (params) => {
      const start = Number(params.start);
      const length = params.length !== null ? Number(params.length) : undefined;

      if (isNaN(start) || (length !== undefined && isNaN(length))) {
        throw new Error('索引和长度必须是有效的数字');
      }

      return params.text.substr(start, length);
    }
  },
  {
    id: 'trim',
    group: 'text',
    name: 'TRIM',
    expression: 'TRIM(文本)',
    description: '移除文本前后的空白字符，并将中间的多个空白字符合并为一个。',
    params: [
      { key: 'text', label: '文本', value: '', placeholder: '输入文本' }
    ],
    variableParams: false, // 不支持动态参数
    calculate: (params) => {
      return params.text.trim().replace(/\s+/g, ' ');
    }
  },
  {
    id: 'upper',
    group: 'text',
    name: 'UPPER',
    expression: 'UPPER(文本)',
    description: '将文本字符串转换为全大写字母。',
    params: [
      { key: 'text', label: '文本', value: '', placeholder: '输入文本' }
    ],
    variableParams: false, // 不支持动态参数
    calculate: (params) => {
      return params.text.toUpperCase();
    }
  },

  // 日期函数 (基于JS Date对象)
  {
    id: 'date',
    group: 'date',
    name: 'DATE',
    expression: 'DATE(年, 月, 日)',
    description: '根据年、月、日创建一个日期对象，并返回YYYY-MM-DD格式的日期。',
    params: [
      { key: 'year', label: '年', type: 'number', value: null, placeholder: '输入年份' },
      { key: 'month', label: '月', type: 'number', value: null, placeholder: '输入月份(1-12)' },
      { key: 'day', label: '日', type: 'number', value: null, placeholder: '输入日期(1-31)' }
    ],
    variableParams: false, // 不支持动态参数
    calculate: (params) => {
      const year = Number(params.year);
      const month = Number(params.month) - 1; // JS月份从0开始
      const day = Number(params.day);

      if (isNaN(year) || isNaN(month) || isNaN(day)) {
        throw new Error('请输入有效的数字');
      }

      const date = new Date(year, month, day);

      // 验证日期有效性
      if (date.getFullYear() !== year || date.getMonth() !== month || date.getDate() !== day) {
        throw new Error('无效的日期');
      }

      return date.toISOString().split('T')[0];
    }
  },
  {
    id: 'dateNow',
    group: 'date',
    name: 'DATENOW',
    expression: 'DATENOW()',
    description: '返回当前日期和时间，格式为YYYY-MM-DD HH:MM:SS。',
    params: [],
    variableParams: false, // 不支持动态参数
    calculate: () => {
      const now = new Date();
      return now.toISOString().replace('T', ' ').slice(0, 19);
    }
  },
  {
    id: 'dateDiff',
    group: 'date',
    name: 'DATEDIFF',
    expression: 'DATEDIFF(开始日期, 结束日期, 单位)',
    description: '计算两个日期之间的差值。单位参数可以是 "Y"（年）、"M"（月）、"D"（日）、"H"（小时）、"Min"（分钟）或 "S"（秒）。',
    params: [
      { key: 'startDate', label: '开始日期', type: 'date', value: '', placeholder: '选择开始日期' },
      { key: 'endDate', label: '结束日期', type: 'date', value: '', placeholder: '选择结束日期' },
      { key: 'unit', label: '单位', value: 'D', placeholder: 'Y=年, M=月, D=日, H=时, Min=分, S=秒' }
    ],
    variableParams: false, // 不支持动态参数
    calculate: (params) => {
      const start = new Date(params.startDate);
      const end = new Date(params.endDate);

      if (isNaN(start.getTime()) || isNaN(end.getTime())) {
        throw new Error('请输入有效的日期');
      }

      const diffTime = end - start;
      const diffDays = diffTime / (1000 * 60 * 60 * 24);

      switch(params.unit.toUpperCase()) {
        case 'Y':
          return Math.floor(diffDays / 365.25);
        case 'M':
          return Math.floor(diffDays / 30.44);
        case 'D':
          return Math.floor(diffDays);
        case 'H':
          return Math.floor(diffTime / (1000 * 60 * 60));
        case 'MIN':
          return Math.floor(diffTime / (1000 * 60));
        case 'S':
          return Math.floor(diffTime / 1000);
        default:
          throw new Error('单位必须是 Y、M、D、H、Min 或 S');
      }
    }
  },
  {
    id: 'day',
    group: 'date',
    name: 'DAY',
    expression: 'DAY(日期)',
    description: '从指定日期中提取日（1-31）。',
    params: [
      { key: 'date', label: '日期', type: 'date', value: '', placeholder: '选择日期' }
    ],
    variableParams: false, // 不支持动态参数
    calculate: (params) => {
      const date = new Date(params.date);
      if (isNaN(date.getTime())) {
        throw new Error('请输入有效的日期');
      }
      return date.getDate();
    }
  },
  {
    id: 'getHours',
    group: 'date',
    name: 'HOUR',
    expression: 'HOUR(日期)',
    description: '从指定日期中提取小时（0-23）。',
    params: [
      { key: 'date', label: '日期', type: 'datetime-local', value: '', placeholder: '选择日期时间' }
    ],
    variableParams: false, // 不支持动态参数
    calculate: (params) => {
      const date = new Date(params.date);
      if (isNaN(date.getTime())) {
        throw new Error('请输入有效的日期时间');
      }
      return date.getHours();
    }
  },
  {
    id: 'getMinutes',
    group: 'date',
    name: 'MINUTE',
    expression: 'MINUTE(日期)',
    description: '从指定日期中提取分钟（0-59）。',
    params: [
      { key: 'date', label: '日期', type: 'datetime-local', value: '', placeholder: '选择日期时间' }
    ],
    variableParams: false, // 不支持动态参数
    calculate: (params) => {
      const date = new Date(params.date);
      if (isNaN(date.getTime())) {
        throw new Error('请输入有效的日期时间');
      }
      return date.getMinutes();
    }
  },
  {
    id: 'getSeconds',
    group: 'date',
    name: 'SECOND',
    expression: 'SECOND(日期)',
    description: '从指定日期中提取秒（0-59）。',
    params: [
      { key: 'date', label: '日期', type: 'datetime-local', value: '', placeholder: '选择日期时间' }
    ],
    variableParams: false, // 不支持动态参数
    calculate: (params) => {
      const date = new Date(params.date);
      if (isNaN(date.getTime())) {
        throw new Error('请输入有效的日期时间');
      }
      return date.getSeconds();
    }
  },
  {
    id: 'month',
    group: 'date',
    name: 'MONTH',
    expression: 'MONTH(日期)',
    description: '从指定日期中提取月份（1-12）。',
    params: [
      { key: 'date', label: '日期', type: 'date', value: '', placeholder: '选择日期' }
    ],
    variableParams: false, // 不支持动态参数
    calculate: (params) => {
      const date = new Date(params.date);
      if (isNaN(date.getTime())) {
        throw new Error('请输入有效的日期');
      }
      return date.getMonth() + 1; // JS月份从0开始，所以+1
    }
  },
  {
    id: 'weekday',
    group: 'date',
    name: 'WEEKDAY',
    expression: 'WEEKDAY(日期)',
    description: '返回指定日期是星期几（1表示星期日，2表示星期一，...，7表示星期六）。',
    params: [
      { key: 'date', label: '日期', type: 'date', value: '', placeholder: '选择日期' }
    ],
    variableParams: false, // 不支持动态参数
    calculate: (params) => {
      const date = new Date(params.date);
      if (isNaN(date.getTime())) {
        throw new Error('请输入有效的日期');
      }
      // getDay()返回0-6，0是星期日，这里转换为1-7
      return date.getDay() + 1;
    }
  },
  {
    id: 'year',
    group: 'date',
    name: 'YEAR',
    expression: 'YEAR(日期)',
    description: '从指定日期中提取年份。返回一个四位数的年份。',
    params: [
      { key: 'date', label: '日期', type: 'date', value: '', placeholder: '选择日期' }
    ],
    variableParams: false, // 不支持动态参数
    calculate: (params) => {
      const date = new Date(params.date);
      if (isNaN(date.getTime())) {
        throw new Error('请输入有效的日期');
      }
      return date.getFullYear();
    }
  },
  // 数组公式 (基于JS数组方法)
  // {
  //   id: 'arrayConcat',
  //   group: 'array',
  //   name: 'ARRAYCONCAT',
  //   expression: 'ARRAYCONCAT(数组1, 数组2)',
  //   description: '将两个数组合并成一个新数组。',
  //   notes: '数组元素用逗号分隔，例如 "1,2,3"',
  //   params: [
  //     { key: 'array1', label: '数组1', value: '', placeholder: '例如: 1,2,3' },
  //     { key: 'array2', label: '数组2', value: '', placeholder: '例如: 4,5,6' }
  //   ],
  //   variableParams: true, // 支持动态参数
  //   paramTemplate: {key: 'array', label: '数组', value: '', placeholder: '例如: 1,2,3'},
  //   calculate: (params) => {
  //     console.log('params', params);
  //     let resArr = [];
  //     for(let k in params) {
  //       const arr = params[k].split(',').map(item => item.trim()).filter(item => item !== '');
  //       console.log('arr', arr);
  //       resArr = resArr.concat(arr);
  //     }
  //     console.log('resArr', resArr);
  //     return resArr.join(",");
  //   }
  // },
  {
    id: 'arrayConcat',
    group: 'array',
    name: 'ARRAYCONCAT',
    expression: 'ARRAYCONCAT(数组1, 数组2, ...)',
    description: '将多个数组合并成一个新数组，保持原有的多维结构。',
    notes: '数组元素用逗号分隔，多维数组用方括号表示，例如 "[1,2],[3,4]" 或 "1,[2,3],4"',
    params: [
      { key: 'array1', label: '数组1', value: '', placeholder: '例如: 1,2,3 或 [1,2],[3,4]' },
      { key: 'array2', label: '数组2', value: '', placeholder: '例如: 4,5,6 或 [5,6],7' }
    ],
    variableParams: true, // 支持动态参数
    paramTemplate: { key: 'array', label: '数组', value: '', placeholder: '例如: 1,2,3 或 [1,2],[3,4]' },
    calculate: (params) => {
      // 解析单个元素，处理可能的多维数组
      const parseElement = (element) => {
        element = element.trim();
        // 如果是多维数组（以[开头并以]结尾）
        if (element.startsWith('[') && element.endsWith(']')) {
          // 去除外层括号后递归解析
          const inner = element.slice(1, -1);
          return parseArray(inner);
        }
        return element;
      };

      // 解析数组字符串为数组，处理其中的多维数组
      const parseArray = (arrayStr) => {
        const result = [];
        let current = '';
        let bracketDepth = 0; // 用于跟踪括号深度，处理嵌套数组

        for (let char of arrayStr) {
          if (char === '[') {
            bracketDepth++;
            current += char;
          } else if (char === ']') {
            bracketDepth--;
            current += char;
          } else if (char === ',' && bracketDepth === 0) {
            // 只有当括号深度为0时的逗号才作为分隔符
            if (current) {
              result.push(parseElement(current));
              current = '';
            }
          } else {
            current += char;
          }
        }

        // 添加最后一个元素
        if (current) {
          result.push(parseElement(current));
        }

        return result;
      };

      // 将数组转换回字符串表示，保持多维结构
      const stringifyArray = (arr) => {
        return arr.map(item => {
          if (Array.isArray(item)) {
            return `[${stringifyArray(item)}]`;
          }
          return item;
        }).join(',');
      };

      let resultArray = [];

      // 处理所有输入参数，使用数组的concat方法进行拼接
      for (let key in params) {
        const paramValue = params[key];
        if (typeof paramValue !== 'string' || paramValue.trim() === '') {
          continue;
        }

        // 解析当前参数为数组（可能包含多维数组）
        const parsedArray = parseArray(paramValue);
        // 使用数组的concat方法拼接，保持多维结构
        resultArray = resultArray.concat(parsedArray);
      }

      // 将结果数组转换为字符串返回，保持多维结构
      return stringifyArray(resultArray);
    }
  },
  {
    id: 'arrayFilter',
    group: 'array',
    name: 'ARRAYFILTER',
    expression: 'ARRAYFILTER(数组, 条件)',
    description: '根据条件过滤数组元素，只保留满足条件的元素。',
    notes: '数组元素用逗号分隔；条件使用x作为变量，如 "x>5" 或 "x%2===0"',
    params: [
      { key: 'array', label: '数组', value: '', placeholder: '例如: 1,2,3,4,5' },
      { key: 'condition', label: '条件', value: '', placeholder: '例如: x>3 或 x%2===0' }
    ],
    variableParams: false, // 不支持动态参数
    calculate: (params) => {
      try {
        const arr = params.array.split(',').map(item => {
          const num = parseFloat(item.trim());
          return isNaN(num) ? item.trim() : num;
        }).filter(item => item !== '');

        // 创建过滤函数
        const filterFunc = new Function('x', `return ${params.condition};`);
        const filtered = arr.filter(filterFunc);

        return filtered.join(', ');
      } catch (e) {
        throw new Error(`过滤条件无效: ${e.message}`);
      }
    }
  },
  {
    id: 'arrayIndexOf',
    group: 'array',
    name: 'ARRAYINDEXOF',
    expression: 'ARRAYINDEXOF(数组, 元素)',
    description: '返回元素在数组中首次出现的位置索引（从0开始），如果未找到则返回-1。',
    notes: '数组元素用逗号分隔',
    params: [
      { key: 'array', label: '数组', value: '', placeholder: '例如: 1,2,3,4,5' },
      { key: 'element', label: '元素', value: '', placeholder: '输入要查找的元素' }
    ],
    variableParams: false, // 不支持动态参数
    calculate: (params) => {
      const arr = params.array.split(',').map(item => item.trim());
      return arr.indexOf(params.element);
    }
  },
  {
    id: 'arrayJoin',
    group: 'array',
    name: 'ARRAYJOIN',
    expression: 'ARRAYJOIN(数组, 分隔符)',
    description: '使用指定的分隔符将数组元素连接成一个字符串。',
    notes: '数组元素用逗号分隔',
    params: [
      { key: 'array', label: '数组', value: '', placeholder: '例如: 1,2,3,4,5' },
      { key: 'separator', label: '分隔符', value: ',', placeholder: '输入分隔符' }
    ],
    variableParams: false, // 不支持动态参数
    calculate: (params) => {
      const arr = params.array.split(',').map(item => item.trim());
      return arr.join(params.separator);
    }
  },
  {
    id: 'arrayLength',
    group: 'array',
    name: 'ARRAYLENGTH',
    expression: 'ARRAYLENGTH(数组)',
    description: '返回数组的长度（元素数量）。',
    notes: '数组元素用逗号分隔',
    params: [
      { key: 'array', label: '数组', value: '', placeholder: '例如: 1,2,3,4,5' }
    ],
    variableParams: false, // 不支持动态参数
    calculate: (params) => {
      const arr = params.array.split(',').map(item => item.trim()).filter(item => item !== '');
      return arr.length;
    }
  },
  {
    id: 'arrayMap',
    group: 'array',
    name: 'ARRAYMAP',
    expression: 'ARRAYMAP(数组, 表达式)',
    description: '对数组中的每个元素应用表达式，并返回新数组。',
    notes: '数组元素用逗号分隔；表达式使用x作为变量，如 "x*2" 或 "x.toUpperCase()"',
    params: [
      { key: 'array', label: '数组', value: '', placeholder: '例如: 1,2,3,4,5' },
      { key: 'expression', label: '表达式', value: '', placeholder: '例如: x*2 或 x+10' }
    ],
    variableParams: false, // 不支持动态参数
    calculate: (params) => {
      try {
        const arr = params.array.split(',').map(item => {
          const num = parseFloat(item.trim());
          return isNaN(num) ? item.trim() : num;
        }).filter(item => item !== '');

        // 创建映射函数
        const mapFunc = new Function('x', `return ${params.expression};`);
        const mapped = arr.map(mapFunc);

        return mapped.join(', ');
      } catch (e) {
        throw new Error(`表达式无效: ${e.message}`);
      }
    }
  },
  {
    id: 'arrayPop',
    group: 'array',
    name: 'ARRAYPOP',
    expression: 'ARRAYPOP(数组)',
    description: '移除并返回数组的最后一个元素。',
    notes: '数组元素用逗号分隔',
    params: [
      { key: 'array', label: '数组', value: '', placeholder: '例如: 1,2,3,4,5' }
    ],
    variableParams: false, // 不支持动态参数
    calculate: (params) => {
      const arr = params.array.split(',').map(item => item.trim()).filter(item => item !== '');
      if (arr.length === 0) throw new Error('数组不能为空');

      const lastElement = arr.pop();
      return `移除的元素: ${lastElement}, 剩余数组: ${arr.join(', ')}`;
    }
  },
  {
    id: 'arrayPush',
    group: 'array',
    name: 'ARRAYPUSH',
    expression: 'ARRAYPUSH(数组, 元素1，元素2，...)',
    description: '向数组的末尾添加一个元素，并返回新的数组。',
    notes: '数组元素用逗号分隔',
    params: [
      { key: 'array', label: '数组', value: '', placeholder: '例如: 1,2,3,4,5' },
      { key: 'element', label: '元素', value: '', placeholder: '输入要添加的元素' }
    ],
    variableParams: true, // 支持动态参数
    paramTemplate: {key: 'element', label: '元素', value: '', placeholder: '输入要添加的元素'},
    calculate: (params) => {
      console.log('params', params);
      const arr = params.array.split(',').map(item => item.trim()).filter(item => item !== '');
      for(let k in params) {
        if(k.includes('element')) {
          arr.push(params[k]);
        }
      }
      return arr.join(', ');
    }
  },
  {
    id: 'arrayReverse',
    group: 'array',
    name: 'ARRAYREVERSE',
    expression: 'ARRAYREVERSE(数组)',
    description: '反转数组中元素的顺序。',
    notes: '数组元素用逗号分隔',
    params: [
      { key: 'array', label: '数组', value: '', placeholder: '例如: 1,2,3,4,5' }
    ],
    variableParams: false, // 不支持动态参数
    calculate: (params) => {
      const arr = params.array.split(',').map(item => item.trim()).filter(item => item !== '');
      return arr.reverse().join(', ');
    }
  },
  {
    id: 'arrayShift',
    group: 'array',
    name: 'ARRAYSHIFT',
    expression: 'ARRAYSHIFT(数组)',
    description: '移除并并返回数组的第一个元素。',
    notes: '数组元素用逗号分隔',
    params: [
      { key: 'array', label: '数组', value: '', placeholder: '例如: 1,2,3,4,5' }
    ],
    variableParams: false, // 不支持动态参数
    calculate: (params) => {
      const arr = params.array.split(',').map(item => item.trim()).filter(item => item !== '');
      if (arr.length === 0) throw new Error('数组不能为空');

      const firstElement = arr.shift();
      return `移除的元素: ${firstElement}, 剩余数组: ${arr.join(', ')}`;
    }
  },
  {
    id: 'arraySlice',
    group: 'array',
    name: 'ARRAYSLICE',
    expression: 'ARRAYSLICE(数组, 开始索引, 结束索引)',
    description: '从数组中提取从开始索引到结束索引（不包含）的元素，返回新数组。',
    notes: '数组元素用逗号分隔',
    params: [
      { key: 'array', label: '数组', value: '', placeholder: '例如: 1,2,3,4,5' },
      { key: 'start', label: '开始索引', type: 'number', value: 0, placeholder: '输入开始索引' },
      { key: 'end', label: '结束索引', type: 'number', value: null, placeholder: '输入结束索引（可选）' }
    ],
    variableParams: false, // 不支持动态参数
    calculate: (params) => {
      const arr = params.array.split(',').map(item => item.trim()).filter(item => item !== '');
      const start = Number(params.start);
      const end = params.end !== null ? Number(params.end) : undefined;

      if (isNaN(start) || (end !== undefined && isNaN(end))) {
        throw new Error('索引必须是有效的数字');
      }

      return arr.slice(start, end).join(', ');
    }
  },
  {
    id: 'arraySort',
    group: 'array',
    name: 'ARRAYSORT',
    expression: 'ARRAYSORT(数组)',
    description: '对数组元素进行排序并返回排序后的数组。',
    notes: '数组元素用逗号分隔；数字按数值排序，字符串按字母顺序排序',
    params: [
      { key: 'array', label: '数组', value: '', placeholder: '例如: 3,1,4,2 或 b,a,d,c' }
    ],
    variableParams: false, // 不支持动态参数
    calculate: (params) => {
      const arr = params.array.split(',').map(item => {
        const num = parseFloat(item.trim());
        return isNaN(num) ? item.trim() : num;
      }).filter(item => item !== '');

      // 排序函数
      arr.sort((a, b) => {
        if (typeof a === 'number' && typeof b === 'number') {
          return a - b;
        }
        return String(a).localeCompare(String(b));
      });

      return arr.join(', ');
    }
  },
  {
    id: 'arrayUnshift',
    group: 'array',
    name: 'ARRAYUNSHIFT',
    expression: 'ARRAYUNSHIFT(数组, 元素1，元素2，...)',
    description: '向数组的开头添加一个元素，并返回新的数组。',
    notes: '数组元素用逗号分隔',
    params: [
      { key: 'array', label: '数组', value: '', placeholder: '例如: 1,2,3,4,5' },
      { key: 'element', label: '元素', value: '', placeholder: '输入要添加的元素' }
    ],
    variableParams: true, // 支持动态参数
    paramTemplate: {key: 'element', label: '元素', value: '', placeholder: '输入要添加的元素'},
    calculate: (params) => {
      const arr = params.array.split(',').map(item => item.trim()).filter(item => item !== '');
      for(let k in params) {
        if(k.includes('element')) {
          arr.unshift(params[k]);
        }
      }
      return arr.join(', ');
    }
  },
  {
    id: 'sumproduct',
    group: 'array',
    name: 'SUMPRODUCT',
    expression: 'SUMPRODUCT(数组1, 数组2)',
    description: '计算两个数组对应元素的乘积之和。两个数组的长度必须相同。',
    notes: '数组元素用逗号分隔，例如 "1,2,3"',
    params: [
      { key: 'array1', label: '数组1', value: '', placeholder: '例如: 1,2,3,4' },
      { key: 'array2', label: '数组2', value: '', placeholder: '例如: 5,6,7,8' }
    ],
    variableParams: false, // 不支持动态参数
    calculate: (params) => {
      // 解析数组
      const arr1 = params.array1.split(',').map(item => parseFloat(item.trim()));
      const arr2 = params.array2.split(',').map(item => parseFloat(item.trim()));

      // 验证数组
      if (arr1.some(isNaN) || arr2.some(isNaN)) {
        throw new Error('数组必须包含有效的数字，用逗号分隔');
      }

      if (arr1.length !== arr2.length) {
        throw new Error('两个数组的长度必须相同');
      }

      if (arr1.length === 0) {
        throw new Error('数组不能为空');
      }

      // 计算乘积之和
      return arr1.reduce((sum, val, index) => sum + val * arr2[index], 0);
    }
  }
];
// 状态管理
const selectedGroup = ref('logical');
const selectedFormula = ref(allFormulas.find(f => f.group === 'logical').id);
const formulaParams = ref([]); // 修改为数组，支持动态参数
const result = ref(null);
const errorMessage = ref('');
const history = ref([]);
const searchQuery = ref(''); // 搜索查询字符串

// 初始化参数
const initializeParams = () => {
  const formula = allFormulas.find(f => f.id === selectedFormula.value);
  if (!formula) return;

  // 初始化参数数组
  const params = formula.params.map(param => ({
    ...param,
    uniqueKey: `${param.key}-${Date.now()}-${Math.random().toString(36).substr(2, 9)}` // 添加唯一标识
  }));

  formulaParams.value = params;
};

// 初始加载
initializeParams();

// 添加新参数
const addParam = () => {
  const formula = currentFormula.value;
  console.log('addParam', formula, formulaParams);
  if (!formula || !formula.variableParams || !formula.paramTemplate) return;

  // 计算新参数的索引
  const paramCount = formulaParams.value.filter(p =>
    p.key.startsWith(formula.paramTemplate.key)
  ).length + 1;
  console.log('paramCount', paramCount);

  // 创建新参数，基于模板并添加唯一标识
  const newParam = {
    ...formula.paramTemplate,
    key: `${formula.paramTemplate.key}${paramCount}`,
    label: `${formula.paramTemplate.label}${paramCount}`,
    uniqueKey: `${formula.paramTemplate.key}-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`
  };

  console.log('newParam', newParam);

  formulaParams.value.push(newParam);
};

// 删除参数
const removeParam = (uniqueKey) => {
  // 确保至少保留一个参数
  if (formulaParams.value.length <= 1) {
    errorMessage.value = '至少需要保留一个参数';
    setTimeout(() => {
      errorMessage.value = '';
    }, 2000);
    return;
  }

  formulaParams.value = formulaParams.value.filter(param => param.uniqueKey !== uniqueKey);
};

// 计算过滤后的公式 - 结合分组和搜索
const filteredFormulas = computed(() => {
  let formulas = allFormulas;

  // 先按分组过滤
  if (selectedGroup.value) {
    formulas = formulas.filter(formula => formula.group === selectedGroup.value);
  }

  // 再按搜索关键词过滤
  if (searchQuery.value) {
    const query = searchQuery.value.toLowerCase();
    formulas = formulas.filter(formula =>
      formula.name.toLowerCase().includes(query) ||
      formula.expression.toLowerCase().includes(query) ||
      formula.description.toLowerCase().includes(query)
    );
  }

  // 如果过滤后没有结果且有搜索词，尝试在所有分组中搜索
  if (formulas.length === 0 && searchQuery.value) {
    const query = searchQuery.value.toLowerCase();
    formulas = allFormulas.filter(formula =>
      formula.name.toLowerCase().includes(query) ||
      formula.expression.toLowerCase().includes(query) ||
      formula.description.toLowerCase().includes(query)
    );
  }

  return formulas;
});

// 当前公式参数
const currentParams = computed(() => {
  return formulaParams.value;
});

// 当前公式信息
const currentFormula = computed(() => {
  return allFormulas.find(f => f.id === selectedFormula.value) || {};
});

// 公式表达式
const currentFormulaExpression = computed(() => {
  return currentFormula.value.expression
    ? currentFormula.value.expression.replace(/(\w+)\((.*?)\)/, '<strong>$1</strong>($2)')
    : '';
});

// 公式描述
const currentFormulaDescription = computed(() => {
  return currentFormula.value.description || '';
});

// 公式备注
const currentFormulaNotes = computed(() => {
  return currentFormula.value.notes || '';
});

// 判断是否可以计算
const isCalculationDisabled = computed(() => {
  // 检查必填参数
  const formula = currentFormula.value;
  if (!formula.params || formula.params.length === 0) return false;

  // 检查是否有至少一个有效参数
  const hasValidParam = formulaParams.value.some(param => {
    const value = param.value;
    return value !== null && value !== undefined && value !== '';
  });

  return !hasValidParam;
});

// 显示结果
const showResult = computed(() => {
  return result.value !== null || errorMessage.value;
});

// 格式化结果显示
const resultDisplay = computed(() => {
  if (errorMessage.value) {
    return `<span class="error">${errorMessage.value}</span>`;
  }

  if (result.value === null) {
    return '';
  }

  // 对数组结果进行特殊格式化
  if (typeof result.value === 'string' && result.value.includes(';')) {
    return result.value.split('; ').map(row => `<div class="array-row">${row}</div>`).join('');
  }

  // 对数字结果进行格式化
  if (typeof result.value === 'number') {
    // 检查是否为整数
    if (Number.isInteger(result.value)) {
      return result.value.toString();
    }
    // 否则保留6位小数
    return result.value.toFixed(6).replace(/0+$/, '').replace(/\.$/, '');
  }

  return result.value;
});


// 选择公式分组
const selectGroup = (groupId) => {
  selectedGroup.value = groupId;
  // 自动选择分组的第一个公式
  const firstFormula = allFormulas.find(f => f.group === groupId);
  if (firstFormula) {
    selectedFormula.value = firstFormula.id;
    resetInputs();
  }
};

// 重置输入
const resetInputs = () => {
  initializeParams();
  result.value = null;
  errorMessage.value = '';
};

// 处理输入变化
const handleInputChange = (e, param) => {
  // 对于数字类型，空值处理为null
  const input = e.target;

  if (param.type === 'number' && input.value === '') {
    param.value = null;
  }
};

// 计算结果
const calculateResult = () => {
  errorMessage.value = '';
  result.value = null;

  try {
    const formula = currentFormula.value;
    if (!formula || !formula.calculate) {
      throw new Error('未找到计算公式');
    }

    // 收集参数值（只保留键和值）
    const params = {};
    formulaParams.value.forEach(param => {
      params[param.key] = param.value;
    });

    // 执行计算
    const calculationResult = formula.calculate(params);
    result.value = calculationResult;

    // 添加到历史记录
    addToHistory(formula, params, calculationResult);
  } catch (err) {
    errorMessage.value = err.message;
  }
};

// 添加到历史记录
const addToHistory = (formula, params, result) => {
  const paramValues = Object.values(params)
    .map(v => v === null ? '' : v)
    .filter(v => v !== '').join(', ');

  const resultText = typeof result === 'object'
    ? JSON.stringify(result)
    : String(result);

  const historyItem = {
    time: new Date().toLocaleString(),
    formula: `${formula.name}(${paramValues})`,
    result: resultText.length > 50 ? resultText.substring(0, 50) + '...' : resultText
  };

  history.value.unshift(historyItem);

  // 限制历史记录数量
  if (history.value.length > 15) {
    history.value.pop();
  }
};

// 清除历史记录
const clearHistory = () => {
  history.value = [];
};

// 清除搜索
const clearSearch = () => {
  searchQuery.value = '';
};

// 监听公式变化，重置参数
watch(selectedFormula, () => {
  resetInputs();
});

// 监听搜索变化，如果有结果则自动选择第一个
watch(searchQuery, (newQuery) => {
  if (newQuery && filteredFormulas.value.length > 0) {
    selectedFormula.value = filteredFormulas.value[0].id;
  } else if (!newQuery) {
    // 如果清除搜索，回到当前分组的第一个公式
    const firstFormula = allFormulas.find(f => f.group === selectedGroup.value);
    if (firstFormula) {
      selectedFormula.value = firstFormula.id;
    }
  }
});
</script>

<template>
  <div class="calculator-container">
    <div class="calculator-app">
      <!-- 页面标题区域 -->
      <header class="app-header">
        <h1>高级公式计算器</h1>
      </header>

      <!-- 主内容区域 -->
      <main class="app-main">
        <!-- 公式搜索框 -->
        <div class="formula-search">
          <label for="formulaSearch">搜索公式:</label>
          <div class="search-input-group">
            <i class="fas fa-search search-icon"></i>
            <input
              id="formulaSearch"
              v-model="searchQuery"
              placeholder="输入公式名称或关键词搜索..."
              class="search-input"
            >
            <button
              class="clear-search-btn"
              @click="clearSearch"
              v-if="searchQuery"
            >
              <i class="fas fa-times"></i>
            </button>
          </div>
          <p class="search-results" v-if="searchQuery">
            找到 {{ filteredFormulas.length }} 个匹配公式
          </p>
        </div>

        <!-- 公式分组和选择器 -->
        <div class="formula-group-selector">
          <label>公式分组:</label>
          <div class="formula-groups">
            <button
              v-for="group in formulaGroups"
              :key="group.id"
              :class="['group-btn', { 'active': selectedGroup === group.id }]"
              @click="selectGroup(group.id)"
            >
              {{ group.name }}
            </button>
          </div>

          <div class="formula-selector">
            <label :for="selectedGroup">选择公式:</label>
            <select
              :id="selectedGroup"
              v-model="selectedFormula"
              @change="resetInputs"
              class="formula-select"
            >
              <option
                v-for="formula in filteredFormulas"
                :key="formula.id"
                :value="formula.id"
              >
                {{ formula.name }} - {{ formula.expression }}
              </option>
            </select>
          </div>
        </div>

        <!-- 公式详情和解释区域 -->
        <div class="formula-details">
          <h3>公式:</h3>
          <div class="formula-expression" v-html="currentFormulaExpression"></div>

          <div class="formula-description">
            <h3>说明:</h3>
            <p>{{ currentFormulaDescription }}</p>
            <p v-if="currentFormulaNotes"><strong>备注:</strong> {{ currentFormulaNotes }}</p>
            <!-- 显示公式是否支持多参数 -->
            <p v-if="currentFormula.variableParams" class="supports-multi-params">
              <i class="fas fa-info-circle"></i> 支持添加多个参数
            </p>
          </div>
        </div>

        <!-- 输入区域 -->
        <div class="input-section">
          <div class="input-header">
            <h3>输入参数:</h3>
            <!-- 只有支持动态参数的公式才显示添加按钮 -->
            <button
              class="add-param-btn"
              @click="addParam"
              v-if="currentFormula.variableParams"
              aria-label="添加参数"
            >
              <i class="fas fa-plus"></i> 添加参数
            </button>
          </div>
          <div class="input-fields">
            <div
              class="input-group"
              v-for="(param, index) in currentParams"
              :key="param.uniqueKey"
            >
              <div class="param-label-container">
                <label :for="param.uniqueKey">{{ param.label }}:</label>
                <!-- 只有支持动态参数且参数数量大于1时才显示删除按钮 -->
                <button
                  class="remove-param-btn"
                  @click="removeParam(param.uniqueKey)"
                  v-if="currentFormula.variableParams && currentParams.length > 1"
                  aria-label="删除参数"
                >
                  <i class="fas fa-times"></i>
                </button>
              </div>
              <input
                :id="param.uniqueKey"
                :type="param.type || 'text'"
                v-model="param.value"
                :placeholder="param.placeholder"
                class="input-field"
                @input="handleInputChange($event, param)"
              >
            </div>
          </div>
        </div>

        <!-- 计算按钮 -->
        <button
          class="calculate-btn"
          @click="calculateResult"
          :disabled="isCalculationDisabled"
        >
          <i class="fas fa-calculator"></i> 计算结果
        </button>

        <!-- 结果展示区域 -->
        <div class="result-section" v-if="showResult">
          <h3>计算结果:</h3>
          <div class="result-value" v-html="resultDisplay"></div>
        </div>

        <!-- 计算历史 -->
        <div class="history-section">
          <div class="history-header">
            <h3>计算历史</h3>
            <button
              class="clear-history-btn"
              @click="clearHistory"
              :disabled="history.length === 0"
            >
              <i class="fas fa-trash-alt"></i> 清除历史
            </button>
          </div>
          <div class="history-content">
            <ul class="history-list" v-if="history.length > 0">
              <li
                class="history-item"
                v-for="(item, index) in history"
                :key="index"
              >
                <span class="history-time">{{ item.time }}</span>
                <span class="history-formula">{{ item.formula }}</span>
                <span class="history-result">{{ item.result }}</span>
              </li>
            </ul>
            <p class="no-history" v-else>暂无计算历史</p>
          </div>
        </div>
      </main>

      <!-- 页脚 -->
      <footer class="app-footer">
        <p>高级公式计算器 &copy; {{ new Date().getFullYear() }}</p>
      </footer>
    </div>
  </div>
</template>

<style>
/* 固定计算器尺寸 */
.calculator-container {
  display: flex;
  justify-content: center;
  padding: 20px;
}

.calculator-app {
  width: 1000px;      /* 固定宽度 */
  display: flex;
  flex-direction: column;
  background-color: #ffffff;
  border-radius: 12px;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
}

/* 标题样式 */
.app-header {
  background-color: #1e40af;
  color: white;
  padding: 20px 30px;
  text-align: center;
  flex-shrink: 0;
}

.app-header h1 {
  font-size: 1.6rem;
  margin-bottom: 5px;
  font-weight: 600;
}

/* 搜索框样式 */
.formula-search {
  margin-bottom: 20px;
}

.formula-search label {
  display: block;
  margin-bottom: 8px;
  font-weight: 600;
  color: #334155;
  font-size: 0.9rem;
}

.search-input-group {
  position: relative;
  display: flex;
  align-items: center;
  margin-bottom: 5px;
}

.search-input {
  width: 100%;
  padding: 10px 12px 10px 36px;
  border: 1px solid #cbd5e1;
  border-radius: 6px;
  font-size: 0.9rem;
  transition: all 0.3s ease;
}

.search-input:focus {
  outline: none;
  border-color: #3b82f6;
  box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
}

.search-icon {
  position: absolute;
  left: 12px;
  color: #94a3b8;
}

.clear-search-btn {
  position: absolute;
  right: 10px;
  background: none;
  border: none;
  color: #94a3b8;
  cursor: pointer;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.2s ease;
}

.clear-search-btn:hover {
  background-color: #f1f5f9;
  color: #334155;
}

.search-results {
  font-size: 0.8rem;
  color: #64748b;
  margin: 0;
  padding-left: 2px;
}

/* 主内容区域 - 可滚动以适应固定高度 */
.app-main {
  padding: 20px;
  overflow-y: auto;
  flex-grow: 1;
}

/* 公式分组选择器 */
.formula-group-selector {
  margin-bottom: 20px;
}

.formula-group-selector label {
  display: block;
  margin-bottom: 8px;
  font-weight: 600;
  color: #334155;
  font-size: 0.9rem;
}

.formula-groups {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 15px;
}

.group-btn {
  background-color: #f1f5f9;
  border: none;
  padding: 6px 12px;
  border-radius: 6px;
  color: #334155;
  font-size: 0.85rem;
  cursor: pointer;
  transition: all 0.2s ease;
}

.group-btn.active {
  background-color: #1e40af;
  color: white;
}

.group-btn:hover:not(.active) {
  background-color: #e2e8f0;
}

/* 公式选择器 */
.formula-selector {
  margin-bottom: 10px;
}

.formula-select {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid #cbd5e1;
  border-radius: 6px;
  font-size: 0.9rem;
  background-color: #ffffff;
  transition: all 0.3s ease;
  color: #1e293b;
}

.formula-select:focus {
  outline: none;
  border-color: #3b82f6;
  box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
}

/* 公式详情区域 */
.formula-details {
  margin-bottom: 20px;
  padding: 15px;
  background-color: #f8fafc;
  border-radius: 6px;
  border-left: 4px solid #3b82f6;
}

.formula-details h3 {
  margin-bottom: 8px;
  color: #1e293b;
  font-size: 1rem;
}

.formula-expression {
  font-family: 'Consolas', 'Monaco', monospace;
  font-size: 1rem;
  padding: 8px 0;
  color: #0f172a;
  margin-bottom: 10px;
  line-height: 1.6;
}

.formula-expression strong {
  color: #1e40af;
}

.formula-description {
  color: #475569;
  font-size: 0.9rem;
}

.formula-description p {
  margin-bottom: 6px;
}

.supports-multi-params {
  color: #059669;
  font-style: italic;
  margin-top: 10px;
  padding: 5px;
  background-color: #f0fdf4;
  border-radius: 4px;
}

/* 输入区域 */
.input-section {
  margin-bottom: 20px;
}

.input-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 12px;
}

.input-section h3 {
  margin: 0;
  color: #334155;
  font-size: 1rem;
}

.add-param-btn {
  background-color: #f1f5f9;
  border: 1px solid #cbd5e1;
  color: #334155;
  padding: 5px 10px;
  border-radius: 4px;
  font-size: 0.85rem;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 5px;
  transition: all 0.2s ease;
  /* 确保按钮可见的样式 */
  min-width: 100px;
  text-align: center;
}

.add-param-btn:hover {
  background-color: #e2e8f0;
  transform: translateY(-1px);
  box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}

.input-fields {
  display: grid;
  grid-template-columns: 1fr;
  gap: 12px;
}

@media (min-width: 768px) {
  .input-fields {
    grid-template-columns: 1fr 1fr;
  }
}

.input-group {
  display: flex;
  flex-direction: column;
}

.param-label-container {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 4px;
}

.input-group label {
  font-weight: 500;
  color: #475569;
  font-size: 0.85rem;
}

.remove-param-btn {
  background: none;
  border: none;
  color: #dc2626;
  cursor: pointer;
  width: 20px;
  height: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  font-size: 0.7rem;
  transition: all 0.2s ease;
}

.remove-param-btn:hover {
  background-color: #fee2e2;
}

.input-field {
  padding: 10px 12px;
  border: 1px solid #cbd5e1;
  border-radius: 6px;
  font-size: 0.9rem;
  transition: all 0.3s ease;
  color: #1e293b;
}

.input-field:focus {
  outline: none;
  border-color: #3b82f6;
  box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
}

/* 按钮样式 */
.calculate-btn {
  width: 100%;
  padding: 12px;
  background-color: #3b82f6;
  color: white;
  border: none;
  border-radius: 6px;
  font-size: 0.95rem;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.3s ease;
  margin-bottom: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
}

.calculate-btn:disabled {
  background-color: #94a3b8;
  cursor: not-allowed;
  transform: none;
  box-shadow: none;
}

.calculate-btn:not(:disabled):hover {
  background-color: #2563eb;
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(59, 130, 246, 0.2);
}

.calculate-btn:not(:disabled):active {
  transform: translateY(0);
  box-shadow: 0 2px 6px rgba(59, 130, 246, 0.2);
}

/* 结果区域 */
.result-section {
  margin-bottom: 20px;
  padding: 15px;
  background-color: #f0fdf4;
  border-radius: 6px;
  border: 1px solid #dcfce7;
}

.result-section h3 {
  margin-bottom: 10px;
  color: #166534;
  font-size: 1rem;
}

.result-value {
  font-size: 1rem;
  line-height: 1.6;
  color: #0f766e;
  font-family: 'Consolas', 'Monaco', monospace;
}

.result-value .error {
  color: #dc2626;
}

.result-value .array-row {
  margin: 3px 0;
  padding-left: 8px;
  border-left: 2px solid #a7f3d0;
}

/* 历史记录区域 */
.history-section {
  margin-top: 20px;
  padding-top: 15px;
  border-top: 1px solid #e2e8f0;
}

.history-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 12px;
}

.history-section h3 {
  color: #334155;
  font-size: 1rem;
}

.clear-history-btn {
  display: flex;
  align-items: center;
  gap: 5px;
  padding: 5px 10px;
  background-color: #f8fafc;
  color: #64748b;
  border: 1px solid #e2e8f0;
  border-radius: 6px;
  font-size: 0.85rem;
  cursor: pointer;
  transition: all 0.2s ease;
}

.clear-history-btn:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.clear-history-btn:not(:disabled):hover {
  background-color: #e2e8f0;
  color: #334155;
}

.history-content {
  max-height: 150px;
  overflow-y: auto;
}

.history-list {
  list-style-type: none;
  padding-right: 10px;
}

.history-item {
  padding: 8px 12px;
  margin-bottom: 8px;
  background-color: #f8fafc;
  border-radius: 6px;
  font-size: 0.85rem;
  color: #475569;
  border-left: 3px solid #94a3b8;
  transition: all 0.2s ease;
}

.history-item:hover {
  background-color: #f1f5f9;
  transform: translateX(2px);
}

.history-time {
  display: inline-block;
  font-size: 0.75rem;
  color: #94a3b8;
  margin-right: 8px;
  min-width: 120px;
}

.history-formula {
  color: #1e40af;
  font-weight: 500;
  margin-right: 8px;
}

.history-result {
  color: #0f766e;
}

.no-history {
  color: #94a3b8;
  font-size: 0.9rem;
  text-align: center;
  padding: 15px;
  background-color: #f8fafc;
  border-radius: 6px;
}

/* 页脚样式 */
.app-footer {
  text-align: center;
  padding: 15px 30px;
  background-color: #f8fafc;
  color: #94a3b8;
  font-size: 0.85rem;
  border-top: 1px solid #e2e8f0;
  flex-shrink: 0;
}

/* 滚动条样式优化 */
::-webkit-scrollbar {
  width: 7px;
  height: 7px;
}

::-webkit-scrollbar-track {
  background: #f1f5f9;
  border-radius: 4px;
}

::-webkit-scrollbar-thumb {
  background: #cbd5e1;
  border-radius: 4px;
}

::-webkit-scrollbar-thumb:hover {
  background: #94a3b8;
}
</style>
